﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml.Linq;
using BanditGame2.Classes;
using BanditGame2.Objects;
using BanditGame2.WCFService;
using Question = BanditGame2.Objects.Question;


namespace BanditGame2
{
    public partial class MainPage : Page
    {

        #region Variables

        //KONSTANTY
        private const int questionPointsConst = 10;     //pocet bodu za otazku, nasoben obtiznosti otazky
        private const int guardPointsConst = 5;     //pocet bodu za zastreleneho strazce, nasobeno obtiznosti strazce
        private const int roundPointsConst = 50;        //maximalni pocet bodu za kolo, pomerovan dosazenym casem
        private const double _BlockSize = 1;
        private const double _ContentWidthtRatio = (double)17 / 21;     //pomocne kontanty pro zobrazeni herniho pole
        private const double _ContentHeightRatio = (double)21 / 23;
        private Duration _playerDuration = new Duration(new TimeSpan(0, 0, 0, 0, 150));
        private Duration _playerSpeedUpDuration = new Duration(new TimeSpan(0, 0, 0, 0, 75));
        private Duration _guard1Duration = new Duration(new TimeSpan(0, 0, 0, 0, 250));
        private Duration _guard2Duration = new Duration(new TimeSpan(0, 0, 0, 0, 150));
        private Duration _guard4Duration = new Duration(new TimeSpan(0, 0, 0, 0, 150));
        private Duration _bullet1Duration = new Duration(new TimeSpan(0, 0, 0, 0, 75));
        private Duration _canonDuration = new Duration(new TimeSpan(0, 0, 0, 0, 120));
        private Duration _blowDuration = new Duration(new TimeSpan(0, 0, 0, 0, 120));
        private Duration _dynamiteTimer = new Duration(new TimeSpan(0, 0, 0, 3));
        private Duration _speedUpTimer = new Duration(new TimeSpan(0, 0, 0, 5));

        private double _ZoomFactor = 1;

        private Direction _lastDirection = Direction.Stop;
        private int _levelIndex;
        private int _levelTime;
        private int _score;
        private int _levelScore;
        private int _lives;
        private int _bonusPoints;
        private int _magazineSize = 3;
        private int _bulletCount = 1;
        private int _speedUpCount = 0;
        private int _bullet1Count = 1;
        private int _canonCount = 0;
        private int _dynamiteCount = 0;
        private bool _isPlaying = false;
        private bool _stopGuardNotTime = false;
        private bool _hint = false;

        private PathSolver _map;    //mapa ulozena jako int pole - slouzi pro vypocet nejkratsi trasy

        private Storyboard storyBoardPlayer = new Storyboard();
        private Storyboard storyBoardGuard1 = new Storyboard();
        private Storyboard storyBoardGuard2 = new Storyboard();
        private Storyboard storyBoardGuard4 = new Storyboard();
        private Storyboard storyBoardBullet1 = new Storyboard();
        private Storyboard storyBoardCanon = new Storyboard();
        private Storyboard storyBoardBlow = new Storyboard();
        private Storyboard storyBoardDynamite = new Storyboard();
        private Storyboard storyBoardSpeedUp = new Storyboard();

        PageSwitcher _pageSwitcher = null;

        private WCFService.Question _currentQuestion = new WCFService.Question();
        private Queue<int> _questionQueue = new Queue<int>();

        private ConfirmEscape _ConfirmEscape = new ConfirmEscape();

        private ModalPopup _ModalPopup = new ModalPopup();

        private Dynamite _currentDynamite;
        private Question _currentQuestionObject;
        private Canon _currentCanon;
        private Round _currentRound;
        private Bandit _currentBandit;
        private Bullet _currentBullet;

        private List<Cell> lstCells = new List<Cell>();
        private List<Guardian> lstGuardians = new List<Guardian>();
        private List<Wall> lstWalls = new List<Wall>();
        private List<Question> lstQuestions = new List<Question>();
        private List<Exit> lstExits = new List<Exit>();

        #endregion

        public MainPage(int levelIndex)
        {
            _levelIndex = levelIndex;
            InitializeComponent();
            try
            {
                storyBoardPlayer.Completed += new EventHandler(storyBoardPlayer_Completed);
                storyBoardGuard1.Completed += new EventHandler(storyBoardGuardian_Completed);
                storyBoardGuard2.Completed += new EventHandler(storyBoardGuardian_Completed);
                storyBoardGuard4.Completed += new EventHandler(storyBoardGuardian_Completed);
                storyBoardBullet1.Completed += new EventHandler(storyBoardBullet1_Completed);
                storyBoardCanon.Completed += new EventHandler(storyBoardCanon_Completed);
                storyBoardBlow.Completed += new EventHandler(storyBoardBlow_Completed);
                storyBoardDynamite.Completed += new EventHandler(storyBoardDynamite_Completed);
                storyBoardSpeedUp.Completed += new EventHandler(storyBoardSpeedUp_Completed);

                //Zobraz uvodni modal popup 
                _ModalPopup.SetValue(Grid.RowSpanProperty, 3);
                _ModalPopup.SetValue(Grid.ColumnSpanProperty, 3);

                DownloadLevelFromSQL(_levelIndex);

                if (_levelIndex == 1)
                {
                    _score = 0;
                    _lives = 3;
                    _bonusPoints = 0;
                    tbMagazine.Text = "Velikost zásobníku: " + _magazineSize;
                    tbSpeedUp.Text = "Zrychlení (S) : " + _speedUpCount;
                    tbDynamite.Text = "Dynamit (V) : " + _dynamiteCount;
                    tbBullet.Text = "Střela (Z) : " + _bulletCount;
                    tbBullet1.Text = "Střela opakovačky (X): " + _bullet1Count;
                    tbCanon.Text = "Střela z kanonu (C) : " + _canonCount;

                    string modalPopupTitle = "Vítejte ve hře Databázový gangster";
                    string modalPopupContent = "• K ovládání hry použijte šipky." + Environment.NewLine + "• Zmáčknutím R resetujete aktuální level." + Environment.NewLine + "• Zmáčknutím ESC vám bude nabídnuto ukončení hry."
                        + Environment.NewLine + "• Odpálení střely kanonu se provádí stiskem mezerníku." + Environment.NewLine + "• Za zodpovězení získáváte 5 bodů násobeno obtížností otázky."
                        + Environment.NewLine + "• Za zabití strážce získáváte 5 bodů násobeno obtížností strážce.";

                    ShowModalPopup(modalPopupTitle, modalPopupContent);
                }

                //Inicializace casovace
                mainTimer.Begin();

                Loaded += new RoutedEventHandler(MainPage_Loaded);
                Unloaded += new RoutedEventHandler(MainPage_Unloaded);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            _pageSwitcher = (PageSwitcher)this.Parent;
        }

        void MainPage_Unloaded(object sender, RoutedEventArgs e)
        {
            storyBoardPlayer.Completed -= new EventHandler(storyBoardPlayer_Completed);
            storyBoardGuard1.Completed -= new EventHandler(storyBoardGuardian_Completed);
            storyBoardGuard2.Completed -= new EventHandler(storyBoardGuardian_Completed);
            storyBoardGuard4.Completed -= new EventHandler(storyBoardGuardian_Completed);
            storyBoardBullet1.Completed -= new EventHandler(storyBoardBullet1_Completed);
            storyBoardCanon.Completed -= new EventHandler(storyBoardCanon_Completed);
            storyBoardBlow.Completed -= new EventHandler(storyBoardBlow_Completed);
            storyBoardDynamite.Completed -= new EventHandler(storyBoardDynamite_Completed);
            storyBoardSpeedUp.Completed -= new EventHandler(storyBoardSpeedUp_Completed);

            mainTimer.Completed -= new EventHandler(timerMain_Completed);

            destroy();
        }

        private void ResetCurrentLevel()
        {
            destroy();

            _levelTime = 0;

            tbTime.Text = "Time: ";
        }

        private void destroy()
        {
            _isPlaying = false;
            _stopGuardNotTime = false;

            if (_pageSwitcher != null) _pageSwitcher.KeyDown -= new KeyEventHandler(ProcessPressedKey);
            _currentBullet = null;
            _currentCanon = null;
            _currentDynamite = null;
            _currentQuestion = null;
            _currentQuestionObject = null;
            _currentBandit = null;
            _currentRound = null;
            _lastDirection = Direction.Stop;
            _map = null;

            mainCanvas.Resources.Clear();
            mainCanvas.Children.Clear();
            lstExits.Clear();
            lstGuardians.Clear();
            lstWalls.Clear();
            lstQuestions.Clear();
            lstCells.Clear();

            storyBoardPlayer.Stop();
            storyBoardPlayer.Children.Clear();
            storyBoardGuard1.Stop();
            storyBoardGuard1.Children.Clear();
            storyBoardGuard2.Stop();
            storyBoardGuard2.Children.Clear();
            storyBoardGuard4.Stop();
            storyBoardGuard4.Children.Clear();
            storyBoardBullet1.Stop();
            storyBoardBullet1.Children.Clear();
            storyBoardCanon.Stop();
            storyBoardCanon.Children.Clear();
            storyBoardBlow.Stop();
            storyBoardSpeedUp.Stop();
            storyBoardDynamite.Stop();
            
        }

        #region Nacitani z db

        /// <summary>
        /// Tato trida vola metody pro nacteni levelu z DB
        /// </summary>
        /// <param name="levelIndex">cislo levelu</param>
        private void DownloadLevelFromSQL(int levelIndex)
        {
            try
            {
                WCFService.WCFServiceClient WCFClient = new WCFService.WCFServiceClient();
                WCFClient.getLevelHeaderCompleted += new EventHandler<WCFService.getLevelHeaderCompletedEventArgs>(WCFClient_getLevelHeaderCompleted);
                WCFClient.getLevelHeaderAsync(levelIndex);
                busyIndicator.IsBusy = true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        /// <summary>
        /// Nacita parametry levelu, nastavuje zobrazeni herniho pole a vola na nacitani jednotlivych policek levelu z DB
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WCFClient_getLevelHeaderCompleted(object sender, getLevelHeaderCompletedEventArgs e)
        {
            _currentRound = e.Result.FirstOrDefault();
            try
            {
                WCFService.WCFServiceClient WCFClient = new WCFService.WCFServiceClient();
                WCFClient.getLevelFieldsCompleted += new EventHandler<WCFService.getLevelFieldsCompletedEventArgs>(WCFClient_getLevelFieldsCompleted);
                WCFClient.getLevelFieldsAsync(_currentRound.Id);

                tbLevelNumber.Text = "Level number: " + _currentRound.Id;
                _levelTime = _currentRound.Time;
                tbTime.Text = ("Time: " + _levelTime);
                SetLevelDimensions();
                _levelScore = 0;
                tbScore.Text = "Score: " + _score;
                tbLives.Text = "Lives: " + _lives;
                _map = new PathSolver(_currentRound.Width, _currentRound.Height);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Nacteni jednotlivych policek z DB
        /// druhy policek:
        ///             0  - zed
        ///             1 - podlaha
        ///             2 - strazce
        ///             3 - otazka
        ///             9 - konec levelu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WCFClient_getLevelFieldsCompleted(object sender, getLevelFieldsCompletedEventArgs e)
        {
            _currentBandit = AddBlock<Bandit>(_currentRound.PlayerX, _currentRound.PlayerY);
            _currentBandit.SetValue(Canvas.ZIndexProperty, 100);

            foreach (Field field in e.Result)
            {

                switch (field.Type)
                {
                    case 0:
                        lstWalls.Add(AddBlock<Wall>(field.X, field.Y));
                        _map[field.X, field.Y] = 1; //Ulozi zed do pomocneho pole pro vypocet nejkratsi vzdalenosti
                        break;

                    case 1:
                        Cell cellInstance = AddBlock<Cell>(field.X, field.Y);
                        lstCells.Add(cellInstance);
                        break;

                    case 2:
                        Cell floorUnderGuardian = AddBlock<Cell>(field.X, field.Y);
                        lstCells.Add(floorUnderGuardian);
                        if ((field.RadiusGuard > 0) && (field.Difficulty > 0) && (field.Difficulty < 5))
                        {
                            Guardian guardianInstance = AddBlock<Guardian>(field.X, field.Y);
                            guardianInstance.SetValue(Canvas.ZIndexProperty, 90);
                            guardianInstance.defaultPosition.Left = field.X;
                            guardianInstance.defaultPosition.Top = field.Y;
                            guardianInstance.Difficulty = field.Difficulty;
                            guardianInstance.Radius = field.RadiusGuard;
                            guardianInstance.IsAlive = true;
                            lstGuardians.Add(guardianInstance);
                        }
                        break;

                    case 3:
                        Cell floorUnderQuestion = AddBlock<Cell>(field.X, field.Y);
                        lstCells.Add(floorUnderQuestion);
                        if ((field.Difficulty > 0) && (field.Difficulty < 5))
                        {
                            Question questionInstance = AddBlock<Question>(field.X, field.Y);
                            questionInstance.SetValue(Canvas.ZIndexProperty, 80);
                            questionInstance.Answered = false;
                            questionInstance.Difficulty = field.Difficulty;
                            lstQuestions.Add(questionInstance);
                        }
                        break;

                    case 9:
                        Exit exitInstance = AddBlock<Exit>(field.X, field.Y);
                        exitInstance.SetValue(Canvas.ZIndexProperty, 80);
                        lstExits.Add(exitInstance);
                        break;
                }
            }
            SetupAnimationPlayer();
            SetupAnimationGuard1();
            SetupAnimationGuard2();
            SetupAnimationBullet1();
            SetupAnimationCanon();
            storyBoardDynamite.Duration = _dynamiteTimer;
            storyBoardSpeedUp.Duration = _speedUpTimer;
            _pageSwitcher.KeyDown += new KeyEventHandler(ProcessPressedKey);

            busyIndicator.IsBusy = false;
        }

        #endregion

        #region herni pole

        /// <summary>
        /// Nastaveni zobrazeni herniho pole
        /// </summary>
        private void SetLevelDimensions()
        {
            if (_currentRound != null)
            {
                LayoutRootGrid.Width = BrowserScreenInformation.ClientWidth;
                LayoutRootGrid.Height = BrowserScreenInformation.ClientHeight;

                //Get Level width and height
                double levelWidth = (_currentRound.Width) * _BlockSize;
                double levelHeight = (_currentRound.Height) * _BlockSize;
                double clientHeight = (LayoutRootGrid.Height) * _ContentHeightRatio;
                double clientWidth = (LayoutRootGrid.Width) * _ContentWidthtRatio;

                double zoomFactorHeight = clientHeight / levelHeight;
                double zoomFactorWidth = clientWidth / levelWidth;

                if (zoomFactorWidth <= zoomFactorHeight)
                {
                    _ZoomFactor = zoomFactorWidth;

                    //Set main canvas left margin
                    double topMargin = (clientHeight - levelHeight * _ZoomFactor) / 2;
                    mainCanvas.SetValue(Canvas.MarginProperty, new Thickness(0, topMargin, 0, topMargin));
                }
                else
                {
                    _ZoomFactor = zoomFactorHeight;

                    //Set main canvas left margin
                    double leftMargin = (clientWidth - levelWidth * _ZoomFactor) / 2;
                    mainCanvas.SetValue(Canvas.MarginProperty, new Thickness(leftMargin, 0, leftMargin, 0));
                }
            }
        }

        /// <summary>
        /// umisteni jednotlivych policek na herni plochu
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="left"></param>
        /// <param name="top"></param>
        /// <returns></returns>
        private T AddBlock<T>(double left, double top) where T : System.Windows.UIElement, IBlockPosition, new()
        {
            T blockInstance = new T();
            mainCanvas.Children.Add(blockInstance);
            blockInstance.SetValue(Canvas.LeftProperty, left * _ZoomFactor);
            blockInstance.SetValue(Canvas.TopProperty, top * _ZoomFactor);

            blockInstance.position.Left = left;
            blockInstance.position.Top = top;

            blockInstance.SetValue(UserControl.WidthProperty, _BlockSize * _ZoomFactor);

            return blockInstance;
        }

        /// <summary>
        /// Metoda vraci policko na danych souradnicich
        /// </summary>
        /// <param name="left"></param>
        /// <param name="top"></param>
        /// <returns></returns>
        public IBlockPosition GetBlockByPosition(double left, double top)
        {
            Wall wallInstance = lstWalls.SingleOrDefault(b => (b.position.Left == left && b.position.Top == top));
            if (wallInstance != null) return wallInstance;

            Question questionInstance = lstQuestions.SingleOrDefault(b => (b.position.Left == left && b.position.Top == top));
            if (questionInstance != null) return questionInstance;

            Cell cellInstance = lstCells.SingleOrDefault(b => (b.position.Left == left && b.position.Top == top));
            if (cellInstance != null) return cellInstance;

            Exit exitInstance = lstExits.SingleOrDefault(b => (b.position.Left == left && b.position.Top == top));
            if (exitInstance != null) return exitInstance;

            throw new Exception("Nerozpoznán typ pole na X:" + left + "Y: " + top);
        }

        private void TransformBlock(IBlockAnimation block, double Left, double top, int stb)
        {
            //if (block.position.Left != Left)
            //{
                block.HorizontalTimeLine.To = Left * _ZoomFactor;
                block.position.Left = Left;
            //}
            //if (block.position.Top != top)
            //{
                block.VerticalTimeLine.To = top * _ZoomFactor;
                block.position.Top = top;
            //}
            switch (stb)
            {//TODO COULD BE ENUM HERE
                case 1:             //storyboard hrace
                    storyBoardPlayer.Begin();
                    break;
                case 2:             //storyboard bandit1
                    storyBoardGuard1.Begin();
                    break;
                case 3:             //storyboard bandit2
                    storyBoardGuard2.Begin();
                    break;
                case 4:             //storyboard bandit 4
                    storyBoardGuard4.Begin();
                    break;
                case 5:             //storyboards bullet
                    storyBoardBullet1.Begin();
                    break;
                case 6:             //storyboards canon
                    storyBoardCanon.Begin();
                    break;
            }
        }

        /// <summary>
        /// Zmena herni plochy a prvku na ni pri zmene velikosti okna prohlizece
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            double oldZoomFactor = _ZoomFactor;

            SetLevelDimensions();

            foreach (Control ctrl in mainCanvas.Children)
            {
                if (typeof(IBlockPosition).IsAssignableFrom(ctrl.GetType()))
                {
                    IBlockPosition block = (IBlockPosition)ctrl;
                    ctrl.SetValue(Canvas.LeftProperty, block.position.Left * _ZoomFactor);
                    ctrl.SetValue(Canvas.TopProperty, block.position.Top * _ZoomFactor);

                    ctrl.SetValue(UserControl.WidthProperty, _BlockSize * _ZoomFactor);

                    if (typeof(IBlockAnimation).IsAssignableFrom(ctrl.GetType()))
                    {
                        IBlockAnimation animationBlock = (IBlockAnimation)ctrl;
                        animationBlock.HorizontalTimeLine.To = animationBlock.position.Left * _ZoomFactor;
                        animationBlock.VerticalTimeLine.To = animationBlock.position.Top * _ZoomFactor;
                    }
                }
            }
        }

        #endregion

        #region Guardian

        /// <summary>
        /// Tato metoda meni obrazek strazce pokud strazce vidi hrace
        /// </summary>
        /// <param name="currentGuardian">instance strazce</param>
        private void SetGuardianActivity(Guardian currentGuardian)
        {
            if (currentGuardian.IsAlive)
            {
                if (currentGuardian.Chasing)
                {
                    string sURL = "../Images/Guardian_Active.png";
                    Uri imgURI = new Uri(sURL, UriKind.Relative);
                    currentGuardian.imgGuardian.Source = new BitmapImage(imgURI);

                    if (currentGuardian.Difficulty == 1 && storyBoardGuard1.GetCurrentState() != ClockState.Active)
                    {
                        int[] field = FindDirection(currentGuardian);
                        if (field != null)
                            MoveGuard(currentGuardian, field[0], field[1]);
                    }
                    if (currentGuardian.Difficulty >= 2 && storyBoardGuard2.GetCurrentState() != ClockState.Active)
                    {
                        int[] field = FindDirection(currentGuardian);
                        if (field != null)
                            MoveGuard(currentGuardian, field[0], field[1]);
                    }
                }
                else
                {
                    string sURL = "../Images/Guardian.png";
                    Uri imgURI = new Uri(sURL, UriKind.Relative);
                    currentGuardian.imgGuardian.Source = new BitmapImage(imgURI);

                    try
                    {
                        if (currentGuardian.Difficulty == 1 && (storyBoardGuard1.GetCurrentState() != ClockState.Active) &&
                            ((currentGuardian.defaultPosition.Left != currentGuardian.position.Left) ||
                             (currentGuardian.defaultPosition.Top != currentGuardian.position.Top)))
                        {
                            int[] field = _map.FindPath((int)currentGuardian.position.Left,
                                                        (int)currentGuardian.position.Top,
                                                        (int)currentGuardian.defaultPosition.Left,
                                                        (int)currentGuardian.defaultPosition.Top);
                            if (field != null)
                                MoveGuard(currentGuardian, field[0], field[1]);
                        }


                        if (currentGuardian.Difficulty >= 2 && (storyBoardGuard2.GetCurrentState() != ClockState.Active) &&
                            ((currentGuardian.defaultPosition.Left != currentGuardian.position.Left) ||
                             (currentGuardian.defaultPosition.Top != currentGuardian.position.Top)))
                        {
                            int[] field = _map.FindPath((int)currentGuardian.position.Left,
                                                        (int)currentGuardian.position.Top,
                                                        (int)currentGuardian.defaultPosition.Left,
                                                        (int)currentGuardian.defaultPosition.Top);
                            if (field != null)
                                MoveGuard(currentGuardian, field[0], field[1]);
                        }
                    }
                    catch (Exception e)
                    {
                        //MessageBox.Show("Chyba pri vypoctu pohybu strazce. " + e.ToString());
                    }

                }
            }
            else
            {
                string sURL = "../Images/Cell.png";
                Uri imgURI = new Uri(sURL, UriKind.Relative);
                currentGuardian.imgGuardian.Source = new BitmapImage(imgURI);
            }
        }

        public void CallGuardianCheck()
        {
            if (_isPlaying && !_stopGuardNotTime)
            {
                foreach (Guardian guardianInstance in lstGuardians)
                {
                    if (guardianInstance.IsAlive)
                    {
                        if ((_currentBandit.position.Left >
                             (guardianInstance.defaultPosition.Left - guardianInstance.Radius)) &&
                            (_currentBandit.position.Left <
                             (guardianInstance.defaultPosition.Left + guardianInstance.Radius)) &&
                            (_currentBandit.position.Top >
                             (guardianInstance.defaultPosition.Top - guardianInstance.Radius)) &&
                            (_currentBandit.position.Top <
                             (guardianInstance.defaultPosition.Top + guardianInstance.Radius)))
                        {
                            //u strazce obtiznosti 1 kontroluje viditelnost  (hrac musi byt na dohled)
                            if (guardianInstance.Difficulty == 1)
                            {
                                if (CheckVisibility(guardianInstance))
                                {
                                    guardianInstance.Chasing = true;
                                }
                                else
                                {
                                    guardianInstance.Chasing = false;
                                }
                            }
                            else
                            {
                                guardianInstance.Chasing = true;
                            }
                        }
                        else
                        {
                            guardianInstance.Chasing = false;
                        }
                        SetGuardianActivity(guardianInstance);
                    }
                    else
                    {
                        string sURL = "../Images/Cell.png";
                        Uri imgURI = new Uri(sURL, UriKind.Relative);
                        guardianInstance.imgGuardian.Source = new BitmapImage(imgURI);
                    }
                }
            }
        }

        /// <summary>
        /// Kontrola viditelnosti mezi hracem a strazcem, kontroluje zda-li na primce mezi stredem hrace a stredem strazce nelezi policko zed
        /// policka ke kontrole jsou ziskavany na zaklade pruseciku dvou primek - jedne ze souradnic a primky mezi hracem a strazcem
        /// </summary>
        /// <param name="guardianInstance"></param>
        /// <returns></returns>
        public bool CheckVisibility(Guardian guardianInstance)
        {
            double[] nvector = new double[2];
            nvector[0] = _currentBandit.position.Top - guardianInstance.position.Top;
            nvector[1] = _currentBandit.position.Left - guardianInstance.position.Left;

            double c = (nvector[1] * (_currentBandit.position.Top + 0.5)) -
                       (nvector[0] * (_currentBandit.position.Left + 0.5));

            double xmin = (Math.Min(_currentBandit.position.Left, guardianInstance.position.Left));
            double xmax = (Math.Max(_currentBandit.position.Left, guardianInstance.position.Left));
            while (xmin < xmax)
            {
                double y = ((((xmin + 1) * nvector[0]) + c) / nvector[1]);
                int yTruncated = (int)y;

                object block = GetBlockByPosition(xmin, yTruncated);
                object block2 = GetBlockByPosition(++xmin, yTruncated);

                if ((block.GetType() == typeof(Wall)) || (block2.GetType() == typeof(Wall)))
                    return false;
            }

            double ymin = (Math.Min(_currentBandit.position.Top, guardianInstance.position.Top));
            double ymax = (Math.Max(_currentBandit.position.Top, guardianInstance.position.Top));
            while (ymin < ymax)
            {
                double x = ((((ymin + 1) * nvector[1]) - c) / nvector[0]);
                int xTruncated = (int)x;

                object block = GetBlockByPosition(xTruncated, ymin);
                object block2 = GetBlockByPosition(xTruncated, ++ymin);

                if ((block.GetType() == typeof(Wall)) || (block2.GetType() == typeof(Wall)))
                    return false;
            }

            return true;
        }

        /// <summary>
        /// hleda nejkratsi cestu k hraci
        /// </summary>
        /// <param name="guardian"></param>
        /// <returns></returns>
        private int[] FindDirection(Guardian currentGuardian)
        {
            try
            {
                int[] nextField = _map.FindPath((int)currentGuardian.position.Left,
                                                   (int)currentGuardian.position.Top,
                                                   (int)_currentBandit.position.Left, (int)_currentBandit.position.Top);
                return nextField;
            }
            catch (Exception e)
            {
                MessageBox.Show("Chyba pri vypoctu pohybu strazce. " + e.ToString());
                return null;
            }
        }

        #endregion

        #region animace

        /// <summary>
        /// Nastaveni animace pohybu hrace
        /// </summary>
        private void SetupAnimationPlayer()
        {
            Duration duration = _playerDuration;
            storyBoardPlayer.Duration = duration;

            //Nastaveni hracovych TimeLines
            AddTimeLine(_currentBandit.VerticalTimeLine, duration, Canvas.TopProperty, _currentBandit, 1);
            AddTimeLine(_currentBandit.HorizontalTimeLine, duration, Canvas.LeftProperty, _currentBandit, 1);

            if (mainCanvas.Resources["stbPlayer"] == null)
            {
                mainCanvas.Resources.Add("stbPlayer", storyBoardPlayer);
            }
        }

        /// <summary>
        /// Nastaveni animace pohybu strazce
        /// </summary>
        private void SetupAnimationGuard1()
        {
            Duration duration = _guard1Duration;
            storyBoardGuard1.Duration = duration;

            //Nastaveni hracovych TimeLines
            foreach (var guardian in lstGuardians)
            {
                if (guardian.Difficulty == 1)
                {
                    AddTimeLine(guardian.VerticalTimeLine, duration, Canvas.TopProperty, guardian, 2);
                    AddTimeLine(guardian.HorizontalTimeLine, duration, Canvas.LeftProperty, guardian, 2);
                }
            }

            if (mainCanvas.Resources["stbGuard1"] == null)
            {
                mainCanvas.Resources.Add("stbGuard1", storyBoardGuard1);
            }
        }
        private void SetupAnimationGuard2()
        {
            Duration duration = _guard2Duration;
            storyBoardGuard2.Duration = duration;

            //Nastaveni hracovych TimeLines
            foreach (var guardian in lstGuardians)
            {
                if (guardian.Difficulty >= 2)
                {
                    AddTimeLine(guardian.VerticalTimeLine, duration, Canvas.TopProperty, guardian, 3);
                    AddTimeLine(guardian.HorizontalTimeLine, duration, Canvas.LeftProperty, guardian, 3);
                }
            }

            if (mainCanvas.Resources["stbGuard2"] == null)
            {
                mainCanvas.Resources.Add("stbGuard2", storyBoardGuard2);
            }
        }
        private void SetupAnimationBullet1()
        {
            Duration duration = _bullet1Duration;
            storyBoardBullet1.Duration = duration;

            if (mainCanvas.Resources["stbBullet1"] == null)
            {
                mainCanvas.Resources.Add("stbBullet1", storyBoardBullet1);
            }
        }
        private void SetupAnimationCanon()
        {
            Duration duration = _canonDuration;
            storyBoardCanon.Duration = duration;

            if (mainCanvas.Resources["stbCanon"] == null)
            {
                mainCanvas.Resources.Add("stbCanon", storyBoardCanon);
            }
        }

        private void AddTimeLine(DoubleAnimation timeLine, Duration duration, DependencyProperty property, DependencyObject targetObject, int stb)
        {
            timeLine.Duration = duration;
            CubicEase easing = new CubicEase();
            easing.EasingMode = EasingMode.EaseIn;
            timeLine.EasingFunction = easing;
            switch (stb)
            {//TODO COULD BE ENUM HERE
                case 1:             //storyboard hrace
                    storyBoardPlayer.Children.Add(timeLine);
                    break;
                case 2:             //storyboard bandit1
                    storyBoardGuard1.Children.Add(timeLine);
                    break;
                case 3:             //storyboard bandit2
                    storyBoardGuard2.Children.Add(timeLine);
                    break;
                case 4:             //storyboard bandit 4
                    storyBoardGuard4.Children.Add(timeLine);
                    break;
                case 5:             //storyboards bullet
                    storyBoardBullet1.Children.Add(timeLine);
                    break;
                case 6:             //storyboards canon
                    storyBoardCanon.Children.Add(timeLine);
                    break;
            }

            Storyboard.SetTarget(timeLine, targetObject);
            Storyboard.SetTargetProperty(timeLine, new PropertyPath(property));
        }

        /// <summary>
        /// Reseni que stisknutych klaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void storyBoardPlayer_Completed(object sender, EventArgs e)
        {
            CallGuardianCheck();  //Kontrola viditelnosti strazcu
        }
        void storyBoardGuardian_Completed(object sender, EventArgs e)
        {
            CallGuardianCheck();

            foreach (Guardian guardian in lstGuardians)
            {
                if (guardian.IsAlive)
                {

                    if ((guardian.position.Top == _currentBandit.position.Top) &&
                        (guardian.position.Left == _currentBandit.position.Left))
                    {
                        if (--_lives > 0)
                        {
                            _currentBandit.HorizontalTimeLine.To = _currentRound.PlayerX*
                                                                   _ZoomFactor;
                            _currentBandit.position.Left = _currentRound.PlayerX;
                            _currentBandit.VerticalTimeLine.To = _currentRound.PlayerY*
                                                                 _ZoomFactor;
                            _currentBandit.position.Top = _currentRound.PlayerY;

                            tbLives.Text = "Lives: " + _lives;
                            storyBoardPlayer.Begin();
                        }
                        else
                        {
                            endOfGame();
                            ShowModalPopup("Game OVER",
                                           "Game OVER." + Environment.NewLine + Environment.NewLine +
                                           "Thank you for playing.");
                        }
                    }
                }
            }
        }
        void storyBoardBullet1_Completed(object sender, EventArgs e)
        {
            if (_currentBullet.Class == 1)
            {
                MoveBullet1(_currentBullet);
            }
            else
            {
                MoveBullet2(_currentBullet);
            }
        }
        void storyBoardCanon_Completed(object sender, EventArgs e)
        {
            if (_currentCanon != null)
                MoveCanon(_currentCanon);
        }
        void storyBoardBlow_Completed(object sender, EventArgs e)
        {

        }
        void storyBoardDynamite_Completed(object sender, EventArgs e)
        {
            if (_currentDynamite != null)
            {
                if ((_currentBandit.position.Top >= (_currentDynamite.position.Top - 1)) &&
                        (_currentBandit.position.Top <= (_currentDynamite.position.Top + 1)) &&
                        (_currentBandit.position.Left >= (_currentDynamite.position.Left - 1)) &&
                        (_currentBandit.position.Left <= (_currentDynamite.position.Left + 1)))
                {
                    if (--_lives > 0)
                    {
                        _currentBandit.HorizontalTimeLine.To = _currentRound.PlayerX *
                                                               _ZoomFactor;
                        _currentBandit.position.Left = _currentRound.PlayerX;
                        _currentBandit.VerticalTimeLine.To = _currentRound.PlayerY *
                                                             _ZoomFactor;
                        _currentBandit.position.Top = _currentRound.PlayerY;

                        storyBoardPlayer.Begin();
                        _stopGuardNotTime = true;
                        tbLives.Text = "Lives: " + _lives;
                    }
                    else
                    {
                        endOfGame();
                        ShowModalPopup("Game OVER",
                                       "Game OVER." + Environment.NewLine + Environment.NewLine +
                                       "Thank you for playing.");
                    }
                }


                foreach (var guardian in lstGuardians.ToList())
                {
                    if (guardian.IsAlive)
                    {
                        if ((guardian.position.Top >= (_currentDynamite.position.Top - 1)) &&
                            (guardian.position.Top <= (_currentDynamite.position.Top + 1)) &&
                            (guardian.position.Left >= (_currentDynamite.position.Left - 1)) &&
                            (guardian.position.Left <= (_currentDynamite.position.Left + 1)))
                        {
                            _levelScore += guardPointsConst*guardian.Difficulty;
                            tbScore.Text = "Score: " + (_score + _levelScore);

                            string sURL = "../Images/Cell.png";
                            Uri imgURI = new Uri(sURL, UriKind.Relative);
                            guardian.imgGuardian.Source = new BitmapImage(imgURI);
                            guardian.IsAlive = false;
                            guardian.SetValue(Canvas.ZIndexProperty, 10);
                            
                            //lstGuardians.Remove(guardian);
                            //mainCanvas.Children.Remove(guardian);
                        }
                    }
                }

                foreach (Wall wall in lstWalls.ToList())
                {
                    if ((wall.position.Top >= (_currentDynamite.position.Top - 1)) &&
                        (wall.position.Top <= (_currentDynamite.position.Top + 1)) &&
                        (wall.position.Left >= (_currentDynamite.position.Left - 1)) &&
                        (wall.position.Left <= (_currentDynamite.position.Left + 1)) &&
                        (wall.position.Left != 0) && (wall.position.Top != 0) &&
                        (wall.position.Left != _currentRound.Width - 1) && (wall.position.Top != _currentRound.Height - 1))
                    {

                        lstWalls.Remove(wall);
                        mainCanvas.Children.Remove(wall);
                        lstCells.Add(AddBlock<Cell>(wall.position.Left, wall.position.Top));
                        _map[(int)wall.position.Left, (int)wall.position.Top] = 0; //Ulozi podlahu do pomocneho pole pro vypocet nejkratsi vzdalenosti
                    }
                }

                mainCanvas.Children.Remove(_currentDynamite);
                _currentDynamite = null;
            }
        }
        void storyBoardSpeedUp_Completed(object sender, EventArgs e)
        {
            storyBoardPlayer.Duration = _playerDuration;
            foreach (var timeline in storyBoardPlayer.Children)
            {
                timeline.Duration = _playerDuration;
            }
        }

        #endregion

        #region pohyb hrace a strazce po poli

        /// <summary>
        /// Pohyb hrace po poli
        /// </summary>
        /// <param name="left"></param>
        /// <param name="top"></param>
        private void MovePlayer(double left, double top)
        {
            try
            {
                object block = GetBlockByPosition(left, top);
                Type blockType = block.GetType();

                if (blockType == typeof(Cell))
                {
                    _isPlaying = true;
                    _stopGuardNotTime = false;
                    TransformBlock(_currentBandit, left, top, 1);
                }

                if (blockType == typeof(Exit))
                {
                    TransformBlock(_currentBandit, left, top, 1);

                    ShowLevelCompletedPopup();
                    _isPlaying = false;
                }

                if (blockType == typeof(Question))
                {
                    

                    TransformBlock(_currentBandit, left, top, 1);

                    _currentQuestionObject = block as Question;
                    if (_currentQuestionObject.Answered == false)
                    {
                        try
                        {
                            WCFService.WCFServiceClient WCFClient = new WCFService.WCFServiceClient();
                            WCFClient.getQuestionCompleted +=
                                new EventHandler<WCFService.getQuestionCompletedEventArgs>(
                                    WCFClient_getQuestionCompleted);
                            ObservableCollection<int> questionArray = new ObservableCollection<int>(_questionQueue.ToArray());
                            WCFClient.getQuestionAsync(_currentQuestionObject.Difficulty, questionArray);
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show(e.Message);
                        }
                    }

                }
            }
            catch (Exception e)
            {
                if (lstWalls.Count > 0)
                    MessageBox.Show(e.ToString());
            }

        }

        /// <summary>
        /// Pohyb strazce po poli
        /// </summary>
        /// <param name="left"></param>
        /// <param name="top"></param>
        private void MoveGuard(Guardian guardian, double left, double top)
        {
            if (guardian.IsAlive)
            {
                Dispatcher.BeginInvoke(() =>
                                           {
                                               try
                                               {
                                                   object block = GetBlockByPosition(left, top);
                                                   Type blockType = block.GetType();
                                                   if (blockType == typeof (Cell) || blockType == typeof (Question) ||
                                                       blockType == typeof (Exit))
                                                   {
                                                       if (guardian.Difficulty == 1)
                                                           TransformBlock(guardian, left, top, 2);
                                                       if (guardian.Difficulty >= 2)
                                                           TransformBlock(guardian, left, top, 3);
                                                   }
                                               }
                                               catch (Exception e)
                                               {
                                                   //MessageBox.Show(e.ToString());
                                               }

                                           });
            }
        }

        /// <summary>
        /// Pohyb kulky po poli
        /// </summary>
        /// <param name="left"></param>
        /// <param name="top"></param>
        private void MoveBullet1(Bullet bullet)
        {
            Dispatcher.BeginInvoke(() =>
                                       {
                                           double lastLeft = bullet.position.Left;
                                           double lastTop = bullet.position.Top;
                                           double left = bullet.position.Left;
                                           double top = bullet.position.Top;

                                           switch (bullet.Direction)
                                           {
                                               case Direction.Up:
                                                   top -= 1;
                                                   lastTop += 1;
                                                   break;
                                               case Direction.Down:
                                                   top += 1;
                                                   lastTop -= 1;
                                                   break;
                                               case Direction.Left:
                                                   left -= 1;
                                                   lastLeft += 1;
                                                   break;
                                               case Direction.Right:
                                                   left += 1;
                                                   lastLeft -= 1;
                                                   break;
                                           }

                                           foreach (var guardian in lstGuardians)
                                           {
                                               if (guardian.IsAlive)
                                               {
                                                   if ((guardian.position.Top == bullet.position.Top &&
                                                        guardian.position.Left == bullet.position.Left) ||
                                                       (guardian.position.Top == lastTop &&
                                                        guardian.position.Left == lastLeft))
                                                   {
                                                       _levelScore += guardPointsConst*guardian.Difficulty;
                                                       tbScore.Text = "Score: " + (_score + _levelScore);
                                                       storyBoardBullet1.Stop();
                                                       storyBoardBullet1.Children.Clear();
                                                       mainCanvas.Children.Remove(_currentBullet);

                                                       string sURL = "../Images/Cell.png";
                                                       Uri imgURI = new Uri(sURL, UriKind.Relative);
                                                       guardian.imgGuardian.Source = new BitmapImage(imgURI);
                                                       guardian.IsAlive = false;
                                                       guardian.SetValue(Canvas.ZIndexProperty, 10);

                                                       //lstGuardians.Remove(guardian);
                                                       //mainCanvas.Children.Remove(guardian);
                                                       _currentBullet = null;
                                                       return;
                                                   }
                                               }
                                           }

                                           try
                                           {
                                               object block = GetBlockByPosition(left, top);
                                               Type blockType = block.GetType();
                                               if (blockType != typeof(Wall))
                                               {
                                                   TransformBlock(bullet, left, top, 5);
                                               }
                                               else
                                               {
                                                   storyBoardBullet1.Stop();
                                                   storyBoardBullet1.Children.Clear();
                                                   mainCanvas.Children.Remove(_currentBullet);
                                                   _currentBullet = null;
                                               }
                                           }
                                           catch (Exception e)
                                           {
                                               MessageBox.Show(e.ToString());
                                           }

                                       });
        }

        /// <summary>
        /// Pohyb kulky po poli
        /// </summary>
        /// <param name="left"></param>
        /// <param name="top"></param>
        private void MoveBullet2(Bullet bullet)
        {
            Dispatcher.BeginInvoke(() =>
            {
                double lastLeft = bullet.position.Left;
                double lastTop = bullet.position.Top;
                double left = bullet.position.Left;
                double top = bullet.position.Top;

                switch (bullet.Direction)
                {
                    case Direction.Up:
                        top -= 1;
                        lastTop += 1;
                        break;
                    case Direction.Down:
                        top += 1;
                        lastTop -= 1;
                        break;
                    case Direction.Left:
                        left -= 1;
                        lastLeft += 1;
                        break;
                    case Direction.Right:
                        left += 1;
                        lastLeft -= 1;
                        break;
                }

                foreach (var guardian in lstGuardians.ToList())
                {
                    if (guardian.IsAlive)
                    {
                        if ((guardian.position.Top == bullet.position.Top &&
                             guardian.position.Left == bullet.position.Left) ||
                            (guardian.position.Top == lastTop && guardian.position.Left == lastLeft))
                        {
                            _levelScore += guardPointsConst*guardian.Difficulty*_currentBullet.Kills;
                            _currentBullet.Kills++;
                            tbScore.Text = "Score: " + (_score + _levelScore);

                            string sURL = "../Images/Cell.png";
                            Uri imgURI = new Uri(sURL, UriKind.Relative);
                            guardian.imgGuardian.Source = new BitmapImage(imgURI);
                            guardian.IsAlive = false;
                            guardian.SetValue(Canvas.ZIndexProperty, 10);
                            
                            
                            //lstGuardians.Remove(guardian);
                            //mainCanvas.Children.Remove(guardian);
                        }
                    }
                }

                try
                {
                    object block = GetBlockByPosition(left, top);
                    Type blockType = block.GetType();
                    if (blockType != typeof(Wall))
                    {
                        TransformBlock(bullet, left, top, 5);
                    }
                    else
                    {
                        storyBoardBullet1.Stop();
                        storyBoardBullet1.Children.Clear();
                        mainCanvas.Children.Remove(_currentBullet);
                        _currentBullet = null;
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }

            });
        }


        /// <summary>
        /// Pohyb kulky po poli
        /// </summary>
        /// <param name="left"></param>
        /// <param name="top"></param>
        private void MoveCanon(Canon canon)
        {
            Dispatcher.BeginInvoke(() =>
            {
                double left = canon.position.Left;
                double top = canon.position.Top;

                switch (canon.Direction)
                {
                    case Direction.Up:
                        top -= 1;
                        break;
                    case Direction.Down:
                        top += 1;
                        break;
                    case Direction.Left:
                        left -= 1;
                        break;
                    case Direction.Right:
                        left += 1;
                        break;
                }

                try
                {
                    object block = GetBlockByPosition(left, top);
                    Type blockType = block.GetType();
                    if (blockType != typeof(Wall))
                    {
                        TransformBlock(canon, left, top, 6);
                    }
                    else
                    {
                        foreach (var guardian in lstGuardians.ToList())
                        {
                            if (guardian.IsAlive)
                            {
                                if ((guardian.position.Top >= (canon.position.Top - 1)) &&
                                    (guardian.position.Top <= (canon.position.Top + 1)) &&
                                    (guardian.position.Left >= (canon.position.Left - 1)) &&
                                    (guardian.position.Left <= (canon.position.Left + 1)))
                                {
                                    _levelScore += guardPointsConst*guardian.Difficulty;
                                    tbScore.Text = "Score: " + (_score + _levelScore);

                                    string sURL = "../Images/Cell.png";
                                    Uri imgURI = new Uri(sURL, UriKind.Relative);
                                    guardian.imgGuardian.Source = new BitmapImage(imgURI);
                                    guardian.IsAlive = false;
                                    guardian.SetValue(Canvas.ZIndexProperty, 10);
                                    //lstGuardians.Remove(guardian);
                                    //mainCanvas.Children.Remove(guardian);
                                }
                            }
                        }

                        storyBoardCanon.Stop();
                        storyBoardCanon.Children.Clear();
                        mainCanvas.Children.Remove(_currentCanon);
                        _currentCanon = null;
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }

            });
        }

        #endregion

        #region otazky

        /// <summary>
        /// Nacteni otazky z DB
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WCFClient_getQuestionCompleted(object sender, getQuestionCompletedEventArgs e)
        {
            _questionQueue.Enqueue(e.Result.Id);
            if (_questionQueue.Count > 9)
                _questionQueue.Dequeue();
            _currentQuestion = e.Result;
            WCFService.WCFServiceClient WCFClient = new WCFService.WCFServiceClient();
            WCFClient.getAnswersCompleted += new EventHandler<WCFService.getAnswersCompletedEventArgs>(WCFClient_getAnswersCompleted);
            WCFClient.getAnswersAsync(e.Result.Id);
        }

        /// <summary>
        /// Zobrazeni okna s otazkou + validace odpovedi
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WCFClient_getAnswersCompleted(object sender, getAnswersCompletedEventArgs e)
        {
            List<Answer> answers = e.Result.ToList();
            QuestionWindow questionWindow = new QuestionWindow(_currentQuestion, answers, _hint);
            questionWindow.Closed += delegate
                                         {
                                             var result = questionWindow.DialogResult;
                                             //Pokud je odpoved spravna
                                             if (result == true)
                                             {
                                                 _levelScore += questionPointsConst * _currentQuestion.Lvl;
                                                 object block = GetBlockByPosition(_currentBandit.position.Left, _currentBandit.position.Top);
                                                 Question questionInstance = block as Question;
                                                 questionInstance.Answered = true;
                                                 string sURL = "../Images/Question_answered.png";
                                                 Uri imgURI = new Uri(sURL, UriKind.Relative);
                                                 questionInstance.imgQuestion.Source = new BitmapImage(imgURI);
                                                 tbScore.Text = "Score: " + (_score + _levelScore);
                                                 
                                                 ChooseBonus chooseBonus = new ChooseBonus(_magazineSize, _bulletCount, _bullet1Count, _canonCount, _dynamiteCount, _speedUpCount);
                                                 chooseBonus.Show();
                                                 chooseBonus.Closed += delegate
                                                                              {
                                                                                  switch (chooseBonus.chosedBonus)
                                                                                  {
                                                                                      case Bonus.bonus.life:
                                                                                          _lives++;
                                                                                          break;
                                                                                      case Bonus.bonus.hint:
                                                                                          _hint = true;
                                                                                          break;
                                                                                      case Bonus.bonus.magazine:
                                                                                          _magazineSize++;
                                                                                          break;    
                                                                                      case Bonus.bonus.bullet:
                                                                                          _bulletCount++;
                                                                                          break;
                                                                                      case Bonus.bonus.bullet1:
                                                                                          _bullet1Count++;
                                                                                          break;
                                                                                      case Bonus.bonus.canon:
                                                                                          _canonCount++;
                                                                                          break;
                                                                                      case Bonus.bonus.dynamite:
                                                                                          _dynamiteCount++;
                                                                                          break;
                                                                                      case Bonus.bonus.speedUp:
                                                                                          _speedUpCount++;
                                                                                          break;
                                                                                  }

                                                                                  tbLives.Text = "Lives: " + _lives;
                                                                                  tbMagazine.Text = "Velikost zásobníku: " + _magazineSize;
                                                                                  tbSpeedUp.Text = "Zrychlení (S) : " + _speedUpCount;
                                                                                  tbDynamite.Text = "Dynamit (V) : " + _dynamiteCount;
                                                                                  tbBullet.Text = "Střela (Z) : " + _bulletCount;
                                                                                  tbBullet1.Text = "Střela opakovačky (X): " + _bullet1Count;
                                                                                  tbCanon.Text = "Střela z kanonu (C) : " + _canonCount;
                                                                                  
                                                                              };
                                                 
                                                 
                                                 
                                                 
                                             }
                                             //Pokud je nespravna nebo hrac otazku vzda
                                             else
                                             {
                                                 if (--_lives > 0)
                                                 {
                                                     //TransformBlock(_currentBandit, _currentRound.PlayerX,
                                                     //               _currentRound.PlayerY, 1);
                                                     _currentBandit.HorizontalTimeLine.To = _currentRound.PlayerX *
                                                                                            _ZoomFactor;
                                                     _currentBandit.position.Left = _currentRound.PlayerX;
                                                     _currentBandit.VerticalTimeLine.To = _currentRound.PlayerY *
                                                                                          _ZoomFactor;
                                                     _currentBandit.position.Top = _currentRound.PlayerY;
                                                     tbLives.Text = "Lives: " + _lives;
                                                     storyBoardPlayer.Begin();
                                                 }
                                                 else
                                                 {
                                                     endOfGame();
                                                     ShowModalPopup("Game OVER", "Game OVER." + Environment.NewLine + Environment.NewLine + "Thank you for playing.");
                                                 }
                                             }
                                         };
            //osetreni prekroceni pole kvuli DelayedKeys
            _currentBandit.HorizontalTimeLine.To = _currentQuestionObject.position.Left * _ZoomFactor;
            _currentBandit.position.Left = _currentQuestionObject.position.Left;
            _currentBandit.VerticalTimeLine.To = _currentQuestionObject.position.Top * _ZoomFactor;
            _currentBandit.position.Top = _currentQuestionObject.position.Top;
            storyBoardPlayer.Begin();
            _stopGuardNotTime = true;
            questionWindow.Show();
        }

        #endregion

        /// <summary>
        /// Metoda volana pri konci hry - ulozi skore a presmeruje na uvodni obrazovku
        /// </summary>
        public void endOfGame()
        {
            try
            {
                WCFService.WCFServiceClient WCFClient = new WCFService.WCFServiceClient();
                WCFClient.insertScoreCompleted += new EventHandler<insertScoreCompletedEventArgs>(WCFClient_insertScoreCompleted);
                WCFClient.insertScoreAsync(App.currentUserLogin, _score, _levelTime); //TODO POSILAT CELKOVY CAS HRY
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        private void WCFClient_insertScoreCompleted(object sender, insertScoreCompletedEventArgs e)
        {
            //_pageSwitcher = null;
            _pageSwitcher.Navigate(new Menu());
        }

        private void ShowLevelCompletedPopup()
        {
            _bonusPoints = (roundPointsConst * (_levelTime)) / _currentRound.Time;
            _score += _levelScore;
            _score += _bonusPoints;

            _levelIndex++;

            try
            {
                WCFService.WCFServiceClient WCFClient = new WCFService.WCFServiceClient();
                WCFClient.checkNextLevelCompleted += new EventHandler<WCFService.checkNextLevelCompletedEventArgs>(WCFClient_checkNextLevelCompleted);
                WCFClient.checkNextLevelAsync(_levelIndex);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        /// <summary>
        /// Konrola existence dalsiho levelu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WCFClient_checkNextLevelCompleted(object sender, checkNextLevelCompletedEventArgs e)
        {
            if (e.Result)
            {
                ShowModalPopup("Konec kola", "Gratulujeme, kolo bylo dokončeno za " + (_currentRound.Time - _levelTime) + " sekund." + Environment.NewLine + "Za tento čas získáváte " + _bonusPoints + " bonusových bodů.");
                ResetCurrentLevel();
                DownloadLevelFromSQL(_levelIndex);
            }
            else
            {
                endOfGame();
                ShowModalPopup("Konec hry", "Gratulujeme, kolo bylo dokončeno za " + (_currentRound.Time - _levelTime) + " sekund." + Environment.NewLine + "Za tento čas získáváte " + _bonusPoints + " bonusových bodů." + Environment.NewLine + Environment.NewLine + "Gratulujeme, dokončil/a jste hru!" + Environment.NewLine + Environment.NewLine + "Děkujeme za hraní.");
                //destroy();
            }
        }

        private void ShowModalPopup(string modalPopupTitle, string modalPopupContent)
        {
            _ModalPopup.lblModalPopupTitle.Content = modalPopupTitle;
            _ModalPopup.lblModalPopoupContent.Content = modalPopupContent;
            _ModalPopup.Show();

        }

        private void ConfirmEscapeClosed(object sender, EventArgs e)
        {
            if (_ConfirmEscape.DialogResult == true)
            {
                destroy();
                _pageSwitcher.Navigate(new Menu());
            }
            else
            {
                _isPlaying = true;
                CallGuardianCheck();
            }
        }

        private void ProcessPressedKey(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Left:
                    if (storyBoardPlayer.GetCurrentState() != ClockState.Active)
                    {
                        _lastDirection = Direction.Left;
                        double targetLeft = _currentBandit.position.Left - (_BlockSize);
                        MovePlayer(targetLeft, _currentBandit.position.Top);
                    }
                    break;
                case Key.Right:
                    if (storyBoardPlayer.GetCurrentState() != ClockState.Active)
                    {
                        _lastDirection = Direction.Right;
                        double targetRight = _currentBandit.position.Left + (_BlockSize);
                        MovePlayer(targetRight, _currentBandit.position.Top);
                    }
                    break;
                case Key.Up:
                    if (storyBoardPlayer.GetCurrentState() != ClockState.Active)
                    {
                        _lastDirection = Direction.Up;
                        double targetTop = _currentBandit.position.Top - (_BlockSize);
                        MovePlayer(_currentBandit.position.Left, targetTop);
                    }
                    break;
                case Key.Down:
                    if (storyBoardPlayer.GetCurrentState() != ClockState.Active)
                    {
                        _lastDirection = Direction.Down;
                        double targetDown = _currentBandit.position.Top + (_BlockSize);
                        MovePlayer(_currentBandit.position.Left, targetDown);
                    }
                    break;
                case Key.R:
                    ResetCurrentLevel();
                    DownloadLevelFromSQL(_levelIndex);
                    break;
                case Key.S:
                    SpeedUp();
                    break;
                case Key.Z:
                    if ((_lastDirection != Direction.Stop) & (_bulletCount > 0))
                    {
                        ShotTheBullet(1);
                        _bulletCount--;
                    }
                    break;
                case Key.X:
                    if ((_lastDirection != Direction.Stop) && (_bullet1Count > 0))
                    {
                        ShotTheBullet(2);
                        _bullet1Count--;
                    }
                    break;
                case Key.C:
                    if ((_lastDirection != Direction.Stop) && (_canonCount > 0))
                    {
                        ShotTheCanon();
                        _canonCount--;
                    }
                    break;
                case Key.V:
                    if (_dynamiteCount > 0)
                    {
                        _dynamiteCount--;
                        PlaceDynamite();   
                    }
                    break;
                case Key.Space:
                    if (_currentCanon != null)
                        BlowTheCanon(_currentCanon);
                    break;
                case Key.Escape:
                    _isPlaying = false;
                    _ConfirmEscape.Show();
                    _ConfirmEscape.Closed += new EventHandler(ConfirmEscapeClosed);
                    break;
            }
        }

        private void PlaceDynamite()
        {
            if (_currentDynamite == null)
                _currentDynamite = AddBlock<Dynamite>(_currentBandit.position.Left, _currentBandit.position.Top);
            storyBoardDynamite.Begin();
        }

        private void BlowTheCanon(Canon canon)
        {
            foreach (var guardian in lstGuardians.ToList())
            {
                if (guardian.IsAlive)
                {
                    if ((guardian.position.Top >= (canon.position.Top - 1)) &&
                        (guardian.position.Top <= (canon.position.Top + 1)) &&
                        (guardian.position.Left >= (canon.position.Left - 1)) &&
                        (guardian.position.Left <= (canon.position.Left + 1)))
                    {
                        _levelScore += guardPointsConst*guardian.Difficulty;
                        tbScore.Text = "Score: " + (_score + _levelScore);

                        string sURL = "../Images/Cell.png";
                        Uri imgURI = new Uri(sURL, UriKind.Relative);
                        guardian.imgGuardian.Source = new BitmapImage(imgURI);
                        guardian.IsAlive = false;
                        guardian.SetValue(Canvas.ZIndexProperty, 10);
                        //lstGuardians.Remove(guardian);
                        //mainCanvas.Children.Remove(guardian);
                    }
                }
            }

            storyBoardCanon.Stop();
            storyBoardCanon.Children.Clear();
            mainCanvas.Children.Remove(_currentCanon);
            _currentCanon = null;
        }

        private void ShotTheCanon()
        {
            if (_currentCanon == null)
            {
                _currentCanon = AddBlock<Canon>(_currentBandit.position.Left, _currentBandit.position.Top);
                _currentCanon.SetValue(Canvas.ZIndexProperty, 90);
                _currentCanon.Direction = _lastDirection;
                AddTimeLine(_currentCanon.VerticalTimeLine, _canonDuration, Canvas.TopProperty, _currentCanon, 6);
                AddTimeLine(_currentCanon.HorizontalTimeLine, _canonDuration, Canvas.LeftProperty, _currentCanon, 6);
                MoveCanon(_currentCanon);
            }
        }

        private void SpeedUp()
        {
            //zmena rychlosti
            storyBoardPlayer.Duration = _playerSpeedUpDuration;
            foreach (var timeline in storyBoardPlayer.Children)
            {
                timeline.Duration = _playerSpeedUpDuration;
            }
            storyBoardSpeedUp.Begin();
        }

        private void ShotTheBullet(int bulletClass)
        {
            if (_currentBullet == null)
            {
                _currentBullet = AddBlock<Bullet>(_currentBandit.position.Left, _currentBandit.position.Top);
                _currentBullet.SetValue(Canvas.ZIndexProperty, 90);
                _currentBullet.Direction = _lastDirection;
                _currentBullet.Class = bulletClass;
                _currentBullet.Kills = 1;
                AddTimeLine(_currentBullet.VerticalTimeLine, _bullet1Duration, Canvas.TopProperty, _currentBullet, 5);
                AddTimeLine(_currentBullet.HorizontalTimeLine, _bullet1Duration, Canvas.LeftProperty, _currentBullet, 5);
                if (_currentBullet.Class == 1)
                {
                    MoveBullet1(_currentBullet);
                }
                else
                {
                    string sURL = "../Images/Bullet2.png";
                    Uri imgURI = new Uri(sURL, UriKind.Relative);
                    _currentBullet.imgBullet.Source = new BitmapImage(imgURI);
                    MoveBullet2(_currentBullet);
                }

            }
        }


        /// <summary>
        /// Timer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerMain_Completed(object sender, EventArgs e)
        {
            if (_isPlaying)
            {
                if (--_levelTime > 0)
                {
                    tbTime.Text = "Time: " + _levelTime.ToString();
                    tbMagazine.Text = "Velikost zásobníku: " + _magazineSize;
                    tbSpeedUp.Text = "Zrychlení (S) : " + _speedUpCount;
                    tbDynamite.Text = "Dynamit (V) : " + _dynamiteCount;
                    tbBullet.Text = "Střela (Z) : " + _bulletCount;
                    tbBullet1.Text = "Střela opakovačky (X): " + _bullet1Count;
                    tbCanon.Text = "Střela z kanonu (C) : " + _canonCount;
                }
                else
                {
                    _lives--;
                    ResetCurrentLevel();
                    DownloadLevelFromSQL(_levelIndex);
                    
                    //endOfGame();
                    //ShowModalPopup("Game OVER", "Konec hry, vypršel čas k vyřešení kola!");
                }
            }
            mainTimer.Begin();
        }

    }
}
